package com.example.voicetoy;


import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements SensorEventListener {

  private int count = 0;
  private static final String TAG = "CharlieJ"; // 日志标签
  private static final int REQUEST_RECORD_AUDIO_PERMISSION = 200; // 请求录音权限的请求码
  private boolean permissionToRecordAccepted = false; // 标记是否获得录音权限
  private String[] permissions = {Manifest.permission.RECORD_AUDIO}; // 需要请求的权限列表

  private AudioRecord audioRecord; // AudioRecord对象，用于录音
  private boolean isRecording = false; // 标记是否正在录音
  private Thread recordingThread; // 录音线程

  private TextView decibelTextView; // 用于显示分贝值的TextView
  private Button startButton; // 开始录音按钮
  private Button stopButton; // 停止录音按钮

  private Handler  // 用于定时更新UI 的Handler 主线程
  handler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message msg) {

      // 处理消息
        // 获取携带的数据
        Bundle bundle = msg.getData();
        String data = bundle.getString("dB");
        // 执行延时任务，每1s 更新一次 UI
      decibelTextView.setText(String.format("Decibel: %.2f dB", Float.parseFloat(data))); // 更新TextView显示


    }
  };







  private SensorManager sensorManager; // 传感器管理器
  private Sensor accelerometer; // 加速度传感器
  private Sensor gyroscope; // 陀螺仪传感器

  private float[] accelerometerValues = new float[3]; // 存储加速度传感器数据的数组
  private float[] gyroscopeValues = new float[3]; // 存储陀螺仪传感器数据的数组


  private List<String> dataBuffer = new ArrayList<>(); // 内存缓冲区，用于暂存数据


  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    decibelTextView = findViewById(R.id.decibelTextView); // 获取TextView实例
    startButton = findViewById(R.id.startButton); // 获取开始按钮实例
    stopButton = findViewById(R.id.stopButton); // 获取停止按钮实例

    // 请求录音权限
    ActivityCompat.requestPermissions(this, permissions, REQUEST_RECORD_AUDIO_PERMISSION);

    // 初始化传感器管理器和传感器
    sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    gyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);

    // 注册传感器监听器
    sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    sensorManager.registerListener(this, gyroscope, SensorManager.SENSOR_DELAY_NORMAL);



    // 设置开始按钮的点击事件
    startButton.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        if (permissionToRecordAccepted) {
          startRecording(); // 开始录音
        } else {
          Toast.makeText(MainActivity.this, "Permission to record audio denied", Toast.LENGTH_SHORT)
              .show();
        }
      }
    });

    // 设置停止按钮的点击事件
    stopButton.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        stopRecording(); // 停止录音
      }
    });

  }

  @Override
  public void onRequestPermissionsResult(int requestCode, String[] permissions,
      int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    permissionToRecordAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED; // 检查是否获得录音权限
    if (!permissionToRecordAccepted) {
      finish(); // 如果没有获得权限，关闭应用
    }
  }

  private void startRecording() {


    int sampleRate = 44100; // 采样率
    int bufferSize = AudioRecord.getMinBufferSize(sampleRate, AudioFormat.CHANNEL_IN_MONO,
        AudioFormat.ENCODING_PCM_16BIT)*2; // 获取最小缓冲区大小

    Log.d("charlieJ","------->" + bufferSize);


    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) !=
        PackageManager.PERMISSION_GRANTED) {
      // TODO: Consider calling
      //    ActivityCompat#requestPermissions
      // here to request the missing permissions, and then overriding
      //   public void onRequestPermissionsResult(int requestCode, String[] permissions, int[]
      //   grantResults)
      // to handle the case where the user grants the permission. See the documentation
      // for ActivityCompat#requestPermissions for more details.
      return;
    }
    audioRecord =
        new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, AudioFormat.CHANNEL_IN_MONO,
            AudioFormat.ENCODING_PCM_16BIT, bufferSize); // 创建AudioRecord对象

    audioRecord.startRecording(); // 开始录音
    isRecording = true; // 设置录音标记为true

    Thread recordingThread = new Thread(new Runnable() {
      @Override
      public void run() {
        writeAudioDataToFile(bufferSize); // 在录音线程中写入音频数据到文件
      }
    }, "AudioRecorder Thread");

    recordingThread.start(); // 启动录音线程


  }

  private void writeAudioDataToFile(int bufferSize) {


    short[] buffer = new short[bufferSize]; // 创建缓冲区
    FileOutputStream fos = null;
    BufferedWriter writer = null;


    while (isRecording) {


      int read = audioRecord.read(buffer, 0, bufferSize); // 从AudioRecord中读取音频数据


      if (read > 0) {
        double sum = 0;
        for (int i = 0; i < read; i++) {
          sum += buffer[i] * buffer[i]; // 计算音频数据的平方和
        }

        if (read > 0) {

          final double amplitude = sum / read; // 计算平均振幅
          final double decibel;

          decibel = 10 * Math.log10(amplitude); // 计算分贝值


          // 获取当前时间的毫秒数
          long currentTimeMillis = System.currentTimeMillis();
          // 将毫秒数转换为秒数
          double currentTimeSeconds = currentTimeMillis / 1000.0;
          // 格式化为小数点后五位的字符串
          DecimalFormat decimalFormat = new DecimalFormat("0.00000");
          String formattedTimestamp = decimalFormat.format(currentTimeSeconds);


          // 格式化数据字符串
          String data = String.format(
              "当前时间：%s，陀螺仪传感器数据：x=%.6f, y=%.6f, z=%.6f，加速度传感器数据：x=%.6f, y=%.6f, z=%.6f，当前分贝：%.6f\n",
              formattedTimestamp,
              gyroscopeValues[0], gyroscopeValues[1], gyroscopeValues[2],
              accelerometerValues[0], accelerometerValues[1], accelerometerValues[2],
              decibel);

          long currentAudioTimestamp = System.nanoTime(); // 获取当前音频数据的时间戳

          if(currentAudioTimestamp-lastSensorTimestamp<=20000000)
          {

            dataBuffer.add(data); // 将数据添加到内存缓冲区
            Log.e("charlieJ","统计数据 条数------->" + count++);
          }

          // 创建消息
          Message message = handler.obtainMessage(1);
          // 创建Bundle对象并添加数据
          Bundle bundle = new Bundle();
          bundle.putString("dB", String.valueOf(decibel));
          // 将Bundle对象设置到消息中
          message.setData(bundle);

          // 发送延时消息，延时1000毫秒（1秒）
          handler.sendMessageDelayed(message, 1000);



        }
      }
    }

  }








  private void stopRecording() {
    if (audioRecord != null) {



      isRecording = false; // 设置录音标记为false
      audioRecord.stop(); // 停止录音
      audioRecord.release(); // 释放AudioRecord资源
      audioRecord = null; // 将AudioRecord对象置为null
      recordingThread = null; // 将录音线程置为null

      handler.removeMessages(1); // 移除定时更新UI的 这条消息




    }


    sensorManager.unregisterListener(this); // 注销传感器监听器

    writeMemoryDataToFile(); // 当录音线程 停止 之后，将list集合 内存缓冲区中的数据 写入 磁盘文件data

      //  --  > gpt ,可以试试。
    // 0  HandlerThreader 开启初始化
    // 1  HandlerThreader 来获取数据，且存内存list
    // 2  stop的时候，给HandlerThreader发消息，让HandlerThreader线程内停止采集
    // 3  HandlerThreader 打印list大小， HandlerThreader继续执行 writeMemoryDataToFile

  }


  private long lastSensorTimestamp = 0;

  @Override
  public void onSensorChanged(SensorEvent event) {

    lastSensorTimestamp = System.nanoTime(); // 更新传感器数据的时间戳
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
      System.arraycopy(event.values, 0, accelerometerValues, 0, event.values.length); // 更新加速度传感器数据
    } else if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
      System.arraycopy(event.values, 0, gyroscopeValues, 0, event.values.length); // 更新陀螺仪传感器数据
    }
  }

  @Override
  public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // Do nothing
  }

  private void writeMemoryDataToFile() {

    FileOutputStream data = null;
    BufferedWriter writer = null;



    try {
      data = openFileOutput("data", Context.MODE_PRIVATE);
      writer = new BufferedWriter(new OutputStreamWriter(data));


      Log.d("charlieJ","------->" + dataBuffer.size());
      for (String str : dataBuffer) {
        writer.write(str); // 将内存缓冲区中的数据写入文件

      }





      dataBuffer.clear(); // 清空内存缓冲区



    } catch (IOException e) {
      Log.e(TAG, "Error writing to file", e); // 捕获并记录异常
    } finally {
      try {
        if (writer != null) {
          writer.close(); // 关闭BufferedWriter
        }
      } catch (IOException e) {
        e.printStackTrace(); // 捕获并记录异常
      }
    }
  }


}